/**
 * Copyright 2025 王小玗
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Attractive Alert库
 * 一个美观易用的弹框库
 * 可拓展性高
 */
class Atal {
    constructor(executor) {
        this.state = 'pending';
        this.value = null;
        this.okCallbacks = [];
        this.cancelCallbacks = [];
        this.customCallbacks = [];
        this.createdCallback = () => {};
        this.closeCallback = () => {};

        const executeCallbacks = (callbacks, value = null) => {
            const copies = callbacks.slice();
            callbacks.length = 0;
            
            copies.forEach(cb => {
                try {
                    value !== null ? cb(value) : cb();
                } catch (error) {
                    console.error('Atal callback error:', error);
                }
            });
        };

        const resolve = (type, value = null) => {
            if (this.state !== 'pending') return;
            
            this.state = type;
            this.value = value;
            
            if (type === 'ok') {
                executeCallbacks(this.okCallbacks);
            } else if (type === 'cancel') {
                executeCallbacks(this.cancelCallbacks);
            } else if (type === 'custom') {
                executeCallbacks(this.customCallbacks, value);
            }
            
            try {
                this.closeCallback();
            } catch (error) {
                console.error('Atal close callback error:', error);
            }
        };

        const ok = () => resolve('ok');
        const cancel = () => resolve('cancel');
        const custom = (value) => resolve('custom', value);
        const close = (fn) => {
            this.closeCallback = fn;
        };

        const created = (value) => {
            this.createdCallback(value);
        };

        try {
            executor(ok, cancel, custom, created, close);
        } catch (error) {
            cancel();
        }

        this._executeCallbacks = executeCallbacks;
    }

    ok(callback) {
        if (this.state === 'ok') {
            callback();
        } else if (this.state === 'pending') {
            this.okCallbacks.push(callback);
        }
        return this;
    }

    cancel(callback) {
        if (this.state === 'cancel') {
            callback();
        } else if (this.state === 'pending') {
            this.cancelCallbacks.push(callback);
        }
        return this;
    }

    custom(callback) {
        if (this.state === 'custom') {
            callback(this.value);
        } else if (this.state === 'pending') {
            this.customCallbacks.push(callback);
        }
        return this;
    }

    created(callback) {
        this.createdCallback = callback;
        return this;
    }

    close(type = 'cancel', value = null) {
        if (this.state !== 'pending') return this;
        
        try {
            this.closeCallback();
        } catch (error) {
            console.error('Atal close callback error:', error);
        }
        
        if (type === 'ok') {
            this.state = 'ok';
            this._executeCallbacks(this.okCallbacks);
        } else if (type === 'cancel') {
            this.state = 'cancel';
            this._executeCallbacks(this.cancelCallbacks);
        } else if (type === 'custom') {
            this.state = 'custom';
            this.value = value;
            this._executeCallbacks(this.customCallbacks, value);
        }
        
        return this;
    }

    static alert() {
        return new Atal((ok, cancel, custom, created, close) => {
            let options;

            if (arguments.length === 1 && typeof arguments[0] === 'object') {
                options = { ...Atal.defaults, ...arguments[0] };
            } else {
                options = { ...Atal.defaults };
                if (arguments.length >= 1) options.title = arguments[0];
                if (arguments.length >= 2) options.content = arguments[1];
                if (arguments.length >= 3) options.icon = arguments[2];
            }

            options.buttons = Atal.processButtons(options.buttons);

            Atal.addStyles();

            const alertElement = Atal.createAlertHTML(options);
            document.body.appendChild(alertElement);

            const overlayElement = alertElement.querySelector('.atal-overlay');

            // 如果不启用动画，移除所有动画样式
            if (!options.animateIcon) {
                const icon = overlayElement.querySelector('.atal-icon');
                if (icon) {
                    const paths = icon.querySelectorAll('*');
                    paths.forEach(path => {
                        path.style.animation = 'none';
                        path.style.strokeDasharray = 'none';
                        path.style.strokeDashoffset = '0';
                        if (path.classList.contains('dot')) {
                            path.style.opacity = '1';
                        }
                    });
                }
            }

            // 设置定时器
            if (options.timer) {
                setTimeout(() => {
                    Atal.closeAlert(alertElement);
                    ok();
                }, options.timer);
            }

            // 绑定按钮事件
            const confirmBtn = overlayElement.querySelector('.atal-confirm');
            if (confirmBtn) {
                confirmBtn.addEventListener('click', () => {
                    Atal.closeAlert(alertElement);
                    ok();
                });
            }

            const cancelBtn = overlayElement.querySelector('.atal-cancel');
            if (cancelBtn) {
                cancelBtn.addEventListener('click', () => {
                    Atal.closeAlert(alertElement);
                    cancel();
                });
            }

            // 绑定自定义按钮事件
            const customBtns = overlayElement.querySelectorAll('.atal-custom');
            customBtns.forEach((btn, index) => {
                btn.addEventListener('click', () => {
                    Atal.closeAlert(alertElement);
                    // 传递自定义按钮的索引和配置信息
                    custom({
                        index: index,
                        button: options.buttons.custom[index]
                    });
                });
            });

            // 点击遮罩层关闭
            overlayElement.addEventListener('click', (e) => {
                if (e.target === overlayElement) {
                    Atal.closeAlert(alertElement);
                    cancel();
                }
            });
            
            close(() => Atal.closeAlert(alertElement));
            Promise.resolve().then(() => {
                created(alertElement);
            });
        });
    }
    // 静态方法 - 处理按钮配置
    static processButtons(buttonsConfig) {
        const result = {
            confirm: null,
            cancel: null,
            custom: []
        };

        // 处理确认按钮
        if (buttonsConfig.confirm !== undefined && buttonsConfig.confirm !== null) {
            if (buttonsConfig.confirm === true) {
                result.confirm = Atal.defaultButtons.confirm;
            } else if (typeof buttonsConfig.confirm === 'string' || typeof buttonsConfig.confirm === 'object') {
                result.confirm = buttonsConfig.confirm;
            }
        }

        // 处理取消按钮
        if (buttonsConfig.cancel !== undefined && buttonsConfig.cancel !== null) {
            if (buttonsConfig.cancel === true) {
                result.cancel = Atal.defaultButtons.cancel;
            } else if (typeof buttonsConfig.cancel === 'string' || typeof buttonsConfig.cancel === 'object') {
                result.cancel = buttonsConfig.cancel;
            }
        }

        // 处理自定义按钮
        if (Array.isArray(buttonsConfig.custom)) {
            result.custom = buttonsConfig.custom.filter(btn => 
                btn !== null && btn !== undefined && btn !== false
            );
        }

        return result;
    }

    // 静态方法 - 设置原生alert
    static native() {
        window.alert = Atal.alert;
    }

    // 静态方法 - 关闭弹窗
    static closeAlert(element) {
        if (element && element.parentNode) {
            element.parentNode.removeChild(element);
        }
    }

    // 静态方法 - 添加样式
    static addStyles() {
        if (document.getElementById('atal-styles')) return;
        const style = document.createElement('style');
        style.id = 'atal-styles';
        style.textContent = Atal.styles;
        document.head.appendChild(style);
    }

    // 静态方法 - 创建弹窗HTML
    static createAlertHTML(options) {
        let iconHTML;
        let iconColor;
        if (typeof options.icon === 'object') {
            iconHTML = options.icon ? Atal.icons[options.icon.type](options.icon.color) || '' : '';
            iconColor = options.icon.color;
        } else if (typeof options.icon === 'string') {
            iconHTML = options.icon ? Atal.icons[options.icon](Atal.getIconColor(options.icon)) || '' : '';
            iconColor = Atal.getIconColor(options.icon);
        } else {
            iconHTML = '';
            iconColor = Atal.getIconColor('');
        }

        let content = '';
        if (options.content instanceof HTMLElement) {
            content = '<div id="atal-custom-content"></div>';
        } else if (typeof options.content === 'string') {
            content = options.html ? options.content : `<p>${Atal.escapeHTML(options.content)}</p>`;
        }

        // 生成自定义按钮HTML
        let customButtonsHTML = '';
        if (options.buttons.custom && options.buttons.custom.length > 0) {
            customButtonsHTML = options.buttons.custom.map((button, index) => {
                return `<button class="atal-button atal-custom" data-index="${index}" style="--icon-color: ${button.color || iconColor}">${button.text}</button>`;
            }).join('');
        }

        let confirmButtonHTML = '';
        if (options.buttons.confirm) {
            if (typeof options.buttons.confirm === "object") {
                confirmButtonHTML = `<button class="atal-button atal-confirm" style="--icon-color: ${options.buttons.confirm.color || iconColor}">${options.buttons.confirm.text}</button>`;
            } else if (typeof options.buttons.confirm === "string") {
                confirmButtonHTML = `<button class="atal-button atal-confirm" style="--icon-color: ${iconColor}">${options.buttons.confirm}</button>`;
            }
        }

        let cancelButtonHTML = '';
        if (options.buttons.cancel) {
            if (typeof options.buttons.cancel === "object") {
                cancelButtonHTML = `<button class="atal-button atal-cancel" style="--icon-color: ${options.buttons.cancel.color || iconColor}">${options.buttons.cancel.text}</button>`;
            } else if (typeof options.buttons.cancel === "string") {
                cancelButtonHTML = `<button class="atal-button atal-cancel" style="--icon-color: ${iconColor}">${options.buttons.cancel}</button>`;
            }
        }

        const alertElement = document.createElement('div');
        alertElement.innerHTML = `
            <div class="atal-overlay">
                <div class="atal-container">
                    <div class="atal-header">
                        ${iconHTML}
                        <h3 class="atal-title">${options.title}</h3>
                    </div>
                    <div class="atal-content" id="atal-content">
                        ${content}
                    </div>
                    <div class="atal-footer">
                        ${cancelButtonHTML}
                        ${customButtonsHTML}
                        ${confirmButtonHTML}
                    </div>
                </div>
            </div>
        `;
        // 处理HTML元素内容
        if (options.content instanceof HTMLElement) {
            const contentContainer = alertElement.querySelector('#atal-custom-content');
            if (contentContainer) {
                contentContainer.appendChild(options.content);
            }
        }
        return alertElement;
    }

    // 静态方法 - 获取图标颜色
    static getIconColor(icon) {
        const colors = {
            success: '#4CAF50', // 绿色
            error: '#F44336',  // 红色
            warning: '#FF9800', // 橙色
            info: '#2196F3',    // 蓝色
            question: '#9C27B0', // 紫色
            heart: '#E91E63',   // 粉色
            star: '#FFC107',    // 黄色
            download: '#2196F3', // 蓝色
            upload: '#2196F3',   // 蓝色
            key: '#FF9800'      // 橙色
        };
        return colors[icon] || '#2196F3'; // 默认蓝色
    }

    // 静态方法 - HTML转义
    static escapeHTML(str) {
        return str.replace(/[&<>"']/g, function (match) {
            switch (match) {
                case '&': return '&amp;';
                case '<': return '&lt;';
                case '>': return '&gt;';
                case '"': return '&quot;';
                case "'": return '&#x27;';
                default: return match;
            }
        });
    }

    static at(defaultOptions) {
        // 创建并返回一个函数，该函数可以使用预设配置
        const atAtal = function() {
            let options;
            
            // 处理不同参数形式
            if (arguments.length === 1 && typeof arguments[0] === 'object') {
                // 单个对象参数
                options = { ...defaultOptions, ...arguments[0] };
            } else {
                // 多个参数形式
                options = { ...defaultOptions };
                if (arguments.length >= 1) options.title = arguments[0];
                if (arguments.length >= 2) options.content = arguments[1];
                if (arguments.length >= 3) options.icon = arguments[2];
            }
            
            // 调用原始的Atal.alert方法
            return Atal.alert(options);
        };
        
        // 复制静态方法和属性
        Object.keys(Atal).forEach(key => {
            if (typeof Atal[key] === 'function' && key !== 'at') {
                atAtal[key] = Atal[key];
            }
        });
        
        // 添加一个方法来更新默认配置
        atAtal.updateDefaults = function(newDefaults) {
            Object.assign(defaultOptions, newDefaults);
        };
        
        // 添加一个方法来获取当前配置
        atAtal.getDefaults = function() {
            return { ...defaultOptions };
        };
        
        // 添加at方法，允许链式创建更深层次at
        atAtal.at = function(newDefaults) {
            return Atal.at({ ...defaultOptions, ...newDefaults });
        };
        
        return atAtal;
    }

	static setDefaults(options) {
    	if (options) {
	        Atal.defaults = {...Atal.defaults, ...options};
	    } else {
	        return Atal.defaults;
	    }
	}
	
	static setDefaultButtons(confirm, cancel) {
		if (confirm === undefined && cancel === undefined) return Atal.defaultButtons;
    	if (confirm !== undefined) Atal.defaultButtons.confirm = confirm;
    	if (cancel !== undefined) Atal.defaultButtons.cancel = cancel;
	}
}

// 静态属性 - 默认配置
Atal.defaults = {
    title: '',
    content: '',
    icon: '',
    buttons: {
        confirm: true, // 使用布尔值表示使用默认按钮
        cancel: false,  // 使用布尔值表示使用默认按钮
        custom: []     // 自定义按钮数组
    },
    timer: null,
    animateIcon: true,
    html: false
};



// 静态属性 - 默认按钮配置
Atal.defaultButtons = {
    confirm: 'OK',
    cancel: 'Cancel'
};

// 静态属性 - 图标
Atal.icons = {
    success: (color) => `
        <svg class="atal-icon success-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="check" d="M20,32l10,10,14-20" style="stroke-dasharray: 44; stroke-dashoffset: 44;"/>
        </svg>
    `,
    error: (color) => `
        <svg class="atal-icon error-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="line line1" d="M24,24L40,40" style="stroke-dasharray: 22.6; stroke-dashoffset: 22.6;"/>
            <path class="line line2" d="M40,24L24,40" style="stroke-dasharray: 22.6; stroke-dashoffset: 22.6;"/>
        </svg>
    `,
    warning: (color) => `
        <svg class="atal-icon warning-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="triangle" d="M32,10L4,54H60L32,10Z" style="stroke-dasharray: 160; stroke-dashoffset: 160;"/>
            <path class="exclamation" d="M32,26V40M32,44V44" style="stroke-dasharray: 22; stroke-dashoffset: 22;"/>
            <path class="dot" d="M32,46a1,1,0,1,1-1,1A1,1,0,0,1,32,46Z" fill="${color}" style="opacity: 0;"/>
        </svg>
    `,
    info: (color) => `
        <svg class="atal-icon info-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="dot" d="M32,16a2,2,0,1,1-2,2A2,2,0,0,1,32,16Z" style="opacity: 0;"/>
            <path class="line" d="M32,28V44" style="stroke-dasharray: 20; stroke-dashoffset: 20; stroke-width: 4;"/>
        </svg>
    `,
    question: (color) => `
        <svg class="atal-icon question-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="question-mark" d="M24,24c0-4,4-8,8-8,6,0,8,4,8,8,0,4-4,6-6,8-2,2-2,6-2,6" style="stroke-dasharray: 60; stroke-dashoffset: 60;"/>
            <path class="dot" d="M32,48a2,2,0,1,1-2,2A2,2,0,0,1,32,48Z" fill="${color}" style="opacity: 0;"/>
        </svg>
    `,
    heart: (color) => `
        <svg class="atal-icon heart-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" fill="none">
            <path class="heart" d="M32,14c5.5-11,22-8.5,22,5.5,0,16.5-22,27.5-22,27.5S10,36,10,19.5C10,6.5,26.5,3,32,14Z" style="stroke-dasharray: 142; stroke-dashoffset: 142;"/>
        </svg>
    `,
    star: (color) => `
        <svg class="atal-icon star-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="star" d="M32,8l8,16,18,2-12,14,2,18-16-10-16,10,2-18L6,26l18-2L32,8Z" style="stroke-dasharray: 181; stroke-dashoffset: 181;"/>
        </svg>
    `,
    download: (color) => `
        <svg class="atal-icon download-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="arrow" d="M32,20V44M32,44L24,36M32,44L40,36" style="stroke-dasharray: 48; stroke-dashoffset: 48;"/>
            <path class="line" d="M20,52H44" style="stroke-dasharray: 24; stroke-dashoffset: 24;"/>
        </svg>
    `,
    upload: (color) => `
        <svg class="atal-icon upload-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="arrow" d="M32,44V20M32,20L24,28M32,20L40,28" style="stroke-dasharray: 48; stroke-dashoffset: 48;"/>
            <path class="line" d="M20,52H44" style="stroke-dasharray: 24; stroke-dashoffset: 24;"/>
        </svg>
    `,
    key: (color) => `
        <svg class="atal-icon key-icon" viewBox="0 0 64 64" stroke="${color}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none">
            <path class="circle" d="M32,4A28,28,0,1,1,4,32,28,28,0,0,1,32,4Z" style="stroke-dasharray: 180; stroke-dashoffset: 180;"/>
            <path class="key-handle" d="M44,32a6,6,0,0,1-6,6,6,6,0,0,1-6-6,6,6,0,0,1,6-6A6,6,0,0,1,44,32Z" style="stroke-dasharray: 38; stroke-dashoffset: 38;"/>
            <path class="key-teeth" d="M44,32H52" style="stroke-dasharray: 8; stroke-dashoffset: 8;"/>
            <path class="key-shaft" d="M32,32H40" style="stroke-dasharray: 8; stroke-dashoffset: 8;"/>
        </svg>
    `
};

// 静态属性 - 样式
Atal.styles = `
    .atal-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 1000;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    }
    
    .atal-container {
        background-color: white;
        border-radius: 16px;
        width: 90%;
        max-width: 420px;
        box-shadow: 0 12px 36px rgba(0, 0, 0, 0.15);
        overflow: hidden;
        animation: atalFadeIn 0.3s ease-out;
    }
    
    .atal-header {
        padding: 30px 25px 15px;
        text-align: center;
    }
    
    .atal-icon {
        width: 80px;
        height: 80px;
        margin-bottom: 20px;
        transform-origin: center;
    }
    
    .atal-title {
        margin: 0;
        font-size: 1.75rem;
        color: #333;
        font-weight: 600;
        letter-spacing: 0.5px;
    }
    
    .atal-content {
        padding: 15px 30px;
        text-align: center;
        color: #555;
        font-size: 1.1rem;
        line-height: 1.6;
    }
    
    .atal-footer {
        display: flex;
        justify-content: center;
        padding: 25px;
        gap: 15px;
        flex-wrap: wrap;
    }
    
    .atal-button {
        padding: 12px 28px;
        border: none;
        border-radius: 8px;
        font-size: 1rem;
        cursor: pointer;
        transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
        font-weight: 500;
        letter-spacing: 0.5px;
        min-width: 80px;
    }
    
    .atal-confirm {
        background-color: var(--icon-color);
        color: white;
    }
    
    .atal-confirm:hover {
        background-color: var(--icon-color);
        filter: brightness(0.9);
        transform: translateY(-2px);
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.12);
    }
    
    .atal-cancel {
        background-color: #f5f5f5;
        color: #666;
        border: 1px solid #ddd;
    }
    
    .atal-cancel:hover {
        background-color: #e5e5e5;
        transform: translateY(-2px);
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
    }
    
    .atal-custom {
        background-color: var(--icon-color, #6c757d);
        color: white;
    }
    
    .atal-custom:hover {
        background-color: var(--icon-color, #5a6268);
        filter: brightness(0.9);
        transform: translateY(-2px);
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.12);
    }
    
    @keyframes atalFadeIn {
        from { opacity: 0; transform: translateY(-20px); }
        to { opacity: 1; transform: translateY(0); }
    }
    
    /* 图标动画 */
    /* 成功图标动画 */
    .success-icon .circle {
        animation: circle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .success-icon .check {
        animation: check-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.5s forwards;
    }
    
    /* 错误图标动画 */
    .error-icon .circle {
        animation: circle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .error-icon .line {
        animation: error-line-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.5s forwards;
    }
    
    .error-icon .line2 {
        animation-delay: 0.8s;
    }
    
    /* 警告图标动画 */
    .warning-icon .triangle {
        animation: triangle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .warning-icon .exclamation {
        animation: exclamation-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.5s forwards;
    }

    .warning-icon .dot {
        animation: dot-anim 0.3s ease-out 0.8s forwards;
    }
    
    /* 信息图标动画 */
    .info-icon .circle {
        animation: circle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .info-icon .line {
        animation: line-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.5s forwards;
    }
    
    .info-icon .dot {
        animation: dot-anim 0.3s ease-out 0.8s forwards;
    }
    
    /* 问题图标动画 */
    .question-icon .circle {
        animation: circle-anim 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .question-icon .question-mark {
        animation: question-anim 0.6s cubic-bezier(0.65, 0, 0.45, 1) 0.6s forwards;
    }
    
    .question-icon .dot {
        animation: dot-anim 0.3s ease-out 1.2s forwards;
    }
    
    /* 心形图标动画 */
    .heart-icon .heart {
        animation: heart-anim 0.5s cubic-bezier(0.65, 0, 0.45, 1) forwards;
        transform-origin: center;
    }
    
    /* 星星图标动画 */
    .star-icon .star {
        animation: star-anim 0.8s cubic-bezier(0.65, 0, 0.45, 1) forwards;
        transform-origin: center;
    }
    
    /* 动画关键帧 */
    @keyframes circle-anim {
        0% { stroke-dashoffset: 180; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes check-anim {
        0% { stroke-dashoffset: 44; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes error-line-anim {
        0% { stroke-dashoffset: 22.6; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes triangle-anim {
        0% { stroke-dashoffset: 150; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes exclamation-anim {
        0% { stroke-dashoffset: 22; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes line-anim {
        0% { stroke-dashoffset: 22; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes dot-anim {
        0% { opacity: 0; transform: scale(0.3); }
        50% { opacity: 1; transform: scale(1.2); }
        100% { opacity: 1; transform: scale(1); }
    }
    
    @keyframes question-anim {
        0% { stroke-dashoffset: 60; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes heart-anim {
        0% { 
            stroke-dashoffset: 120;
            transform: scale(0.8);
        }
        50% {
            stroke-dashoffset: 60;
            transform: scale(1.1);
        }
        100% { 
            stroke-dashoffset: 0;
            transform: scale(1);
        }
    }
    
    @keyframes star-anim {
        0% { 
            stroke-dashoffset: 150;
            transform: scale(0.8) rotate(-30deg);
            opacity: 0;
        }
        50% {
            stroke-dashoffset: 75;
            transform: scale(1.1) rotate(10deg);
            opacity: 1;
        }
        100% { 
            stroke-dashoffset: 0;
            transform: scale(1) rotate(0);
            opacity: 1;
        }
    }
    /* 下载图标动画 */
    .download-icon .circle {
        animation: circle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .download-icon .arrow {
        animation: download-arrow-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) 0.4s forwards;
    }
    
    .download-icon .line {
        animation: download-line-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
    }
    
    /* 上传图标动画 */
    .upload-icon .circle {
        animation: circle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .upload-icon .arrow {
        animation: upload-arrow-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) 0.4s forwards;
    }
    
    .upload-icon .line {
        animation: upload-line-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
    }
    
    /* 钥匙图标动画 */
    .key-icon .circle {
        animation: circle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) forwards;
    }
    
    .key-icon .key-handle {
        animation: key-handle-anim 0.4s cubic-bezier(0.65, 0, 0.45, 1) 0.4s forwards;
    }
    
    .key-icon .key-teeth {
        animation: key-teeth-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;
    }
    
    .key-icon .key-shaft {
        animation: key-shaft-anim 0.3s cubic-bezier(0.65, 0, 0.45, 1) 1.1s forwards;
    }
    
    /* 新增动画关键帧 */
    @keyframes download-arrow-anim {
        0% { stroke-dashoffset: 48; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes download-line-anim {
        0% { stroke-dashoffset: 24; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes upload-arrow-anim {
        0% { stroke-dashoffset: 48; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes upload-line-anim {
        0% { stroke-dashoffset: 24; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes key-handle-anim {
        0% { 
            stroke-dashoffset: 38;
            transform: scale(0.8);
        }
        100% { 
            stroke-dashoffset: 0;
            transform: scale(1);
        }
    }
    
    @keyframes key-teeth-anim {
        0% { stroke-dashoffset: 8; }
        100% { stroke-dashoffset: 0; }
    }
    
    @keyframes key-shaft-anim {
        0% { stroke-dashoffset: 8; }
        100% { stroke-dashoffset: 0; }
    }
`;

window.Atal = Atal;
